/**
 * @Author: zhongyang
 * @Date: 2022/6/25 13:50
 */

package main

import "fmt"

/**
06_建造者模式
概念：将一个复杂对象的构建与它的表示分离，使得同样的构建过程可以创建不同的表示。
拿手机举例：他的各个部件都是由不同厂商生产，最终构建出一个完整的手机（对象）

与工厂模式的区别：
工厂模式生产出来的对象都是一样的，而建造者模式则不同，建造者模式部件根据调用顺序的异同会产生不同的对象，而工厂模式的生产方式是一致的。
总而言之：当对象非常复杂时才会考虑使用建造者模式。
*/

// ===============1.建造者接口===============

type Builder interface {
	Part1()
	Part2()
	Part3()
}

// ===============2.建造者对象及操作==============

type Director struct {
	Builder
}

func NewDirector(builder Builder) *Director {
	return &Director{Builder: builder}
}

func (d *Director) MakeData() {
	d.Builder.Part1()
	d.Builder.Part2()
	d.Builder.Part3()
}

// ==================3.建造者实例==============

type StringBuilder struct {
	result string
}

func (s *StringBuilder) Part1() {
	s.result += "1"
}
func (s *StringBuilder) Part2() {
	s.result += "2"
}
func (s *StringBuilder) Part3() {
	s.result += "3"
}

func (s *StringBuilder) Result() string {
	return s.result
}

//int建造者
type IntBuilder struct {
	result int64
}

func (ib *IntBuilder) Part1() {
	ib.result = ib.result + 1
}
func (ib *IntBuilder) Part2() {
	ib.result = ib.result + 2
}
func (ib *IntBuilder) Part3() {
	ib.result = ib.result + 3
}
func (ib *IntBuilder) Result() int64 {
	return ib.result
}

func main() {
	builder := &StringBuilder{}
	//builder := &IntBuilder{}
	director := NewDirector(builder)
	director.MakeData()
	fmt.Println(builder.Result())
}
